<?php

namespace app\admin\model;

use app\common\model\Category;
use Overtrue\Pinyin\Pinyin;
use services\QCloudSmsService;
use think\Db;
use think\db\Query;
use think\Exception;
use think\Model;


class Reservation extends Model
{

    // 表名
    protected $name = 'reservation';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = false;

    // 定义时间戳字段名
    protected $createTime = false;
    protected $updateTime = false;
    protected $deleteTime = false;

    protected $resultSetType = 'collection';

    // 追加属性
    protected $append = [
        'delete_time_text',
        'disease_id_text'
    ];

    public function user()
    {
        return $this->belongsTo(\app\common\model\User::class, 'uid', 'id');
    }

    public function getDeleteTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['delete_time']) ? $data['delete_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    protected function setDeleteTimeAttr($value)
    {
        return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
    }

    public function getDiseaseIdTextAttr($value, $data)
    {
        return Category::where('id', $data['disease_id'])->value('name');
    }

    /**
     * Description:
     *
     * @param $row
     * @param $params
     * @param $adminIds
     *
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function changeOrder(array $row, $adminIds = 0)
    {
        $conf       = new \app\admin\model\Pmsconfig;
        $order_flag = $conf->getvalue('order_flag');
        $oi         = new \app\admin\model\Pmsorderinfo;

        if (!isset($row['id_sk']) && !$this->where('id', $row['id'])->count()) {
            exception('错误预订单');
        }

        $stayTime = strtotime(date('Y-m-d', strtotime($row['stay_date'])));
        $liveTime = isset($row['out_date']) ? strtotime($row['out_date']) : $stayTime + ($row['stay_days'] * 86400);

        if (isset($row['room_info']) && $row['room_info']) {
            [$roomId, $roomTypeId] = explode(',', $row['room_info']);
            $roomL = [['id' => $roomId, 'room_type' => $roomTypeId]];
        } else {
            $roomL = (new \app\admin\model\Pmsroominfo())
                ->where('state', 1)
                // ->where('room_status', 0)
                ->where('is_lock', 0)
                ->where('is_dirty', 0)
                ->where('is_repair', 0)
                ->select()->toArray();
        }
        $room = $this->checkStayRoom($roomL, $stayTime, $liveTime);

        $row['room_type_id'] = $room['room_type'];
        $row['room_info_id'] = $room['id'];

        [$pinyin, $sname, $birth, $sex] = $this->getMemberInfo($row['patient_name'], $row['patient_cardno']);
        $data = [
            'reserve_id'     => $row['id'] ?? 0,
            'uid'            => $row['uid'] ?? 0,
            'disease_id'     => $row['disease_id'] ?? 0,
            'source'         => $row['source'] ?? 'h5',
            'order_no'       => $oi->create_order_no($order_flag),
            'realname'       => $row['patient_name'],
            'sname'          => $sname,
            'pinyin'         => $pinyin,
            'person_no'      => $row['patient_cardno'],
            'sex'            => $sex,
            'nation'         => $row['nation'] ?? '汉族',
            'birthday'       => strtotime($row['birthday'] ?? $birth),
            'tel'            => $row['tel'] ?? $row['accompany_mobile'] ?? '',
            'check_in_time'  => $stayTime,
            'check_out_time' => $liveTime,
            'days'           => $row['stay_days'],
            'remarks'        => $row['memo'],
            'createtime'     => time(),
            'creator'        => $adminIds,
            'updatetime'     => time(),
            'last_editor'    => $adminIds,
            'room_info_id'   => $row['room_info_id'] ?? 0,
            'room_type_id'   => $row['room_type_id'] ?? 0,
        ];

        // 如果住院时间是当天 状态则为已住院
        if($stayTime == strtotime(date('Y-m-d'))){
            $data['order_status'] = 0;
        }
        $order_id = $oi->insertGetId($data);

        [$pinyin, $sname, $birth, $sex] = $this->getMemberInfo($row['accompany_name'], $row['accompany_cardno']);
        Db::name('pms_order_people_list')->insert([
            'order_id'          => $order_id,
            'user_id'           => $row['uid'] ?? 0,
            'realname'          => $row['accompany_name'],
            'sname'             => $sname,
            'pinyin'            => $pinyin,
            'birthday'          => $row['accompany_birthday'] ?? $birth,
            'sex'               => $row['accompany_sex'] ?? $sex,
            'certificates_type' => '身份证',
            'person_no'         => $row['accompany_cardno'],
            'tel'               => $row['accompany_mobile'],
            'state'             => 0,
            'createtime'        => time(),
            'creator'           => $adminIds
        ]);

        isset($row['id']) && $this->where('id', $row['id'])->update(['room_type_id' => $room['room_type'], 'room_info_id' => $room['id']]);
        // 发送短信通知
        isset($row['id']) && QCloudSmsService::create($row['accompany_mobile'])->sendReserSucSms($row['stay_date']);
    }

    /**
     * Description:
     *
     * @param array $row
     *
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function cancelOrder(array $row, bool $sendSms = false)
    {
        $this->where('id', $row['id'])->update(['status' => 2]);
        if (!$sendSms) {
            (new \app\admin\model\Pmsorderinfo())->where('reserve_id', $row['id'])->update(['order_status' => 2]);
        }
        if ($sendSms) {
            QCloudSmsService::create($row['accompany_mobile'])->sendReserFailSms($row['stay_date']);
        }
    }

    public function getMemberInfo($name, $cardNo)
    {
        $birth       = $cardNo ? strlen($cardNo) == 15 ? ('19' . substr($cardNo, 6, 6)) : substr($cardNo, 6, 8) : '';
        $sex         = $cardNo ? substr($cardNo, -2, 1) % 2 ? '1' : '0' : '0'; //1为男 2为女
        $pinyinArray = (new Pinyin())->convert($name);
        $pinyin      = '';
        $sname       = '';
        foreach ($pinyinArray as $item) {
            $pinyin .= $item;
            $sname  .= ucwords(substr($item, 0, 1));
        }
        return [$pinyin, $sname, $birth, $sex];
    }

    public function checkStayRoom(array $roomList, int $inTime, int $outTime)
    {
        $room = [];
        $oi   = (new Pmsorderinfo());

        $reserveDates = setFormatDate($inTime, $outTime);
        foreach ($roomList as $r) {
            $orderList = $oi->where(['room_info_id' => $r['id']])->whereIn('order_status', [-1, 0])->field('id,check_in_time,check_out_time')->select()->toArray();
            if (empty($orderList)) {
                $room = $r;
                break;
            }
            foreach ($orderList as $orderI) {
                $orderI['date'] = setFormatDate($orderI['check_in_time'], $orderI['check_out_time']);
                if (!empty(array_intersect($reserveDates, $orderI['date']))) {
                    break;
                }
            }
            $room = $r;
        }
        if (empty($room)) {
            exception(__('与实际当前开放床位空余时间冲突，请重新选择住院日期或解锁床位！'));
        }
        return $room;
    }

}

